#include "Task.hpp"

const int processNum = 5;
vector<task_t> tasks; // 任务列表

class Channel
{
public:
	Channel(int pipefd, int childpid, string processname)
		: _pipefd(pipefd), _childpid(childpid), _processname(processname)
	{
	}
	~Channel() {}
public:
	int _pipefd;		 // 管道的文件描述符
	pid_t _childpid;	 // 发送给哪个的子进程
	string _processname; // 子进程的名字
};

void Slaver()
{
	while (1)
	{
		// cout << "rfd: " << rfd << endl;
		int taskCode = 0;						 // 任务码
		int n = read(0, &taskCode, sizeof(int)); // 如果父进程不给子进程发送任务呢？ 阻塞等待
		if (n == sizeof(int))
		{
			// 执行任务码对应的任务
			cout << "child: " << getpid() << ", get taskCode: " << taskCode << endl;
			if (taskCode >= 0 && taskCode < 4)
				tasks[taskCode](); // 执行任务
		}
		if (n == 0)	
		{
			cout << "child: " << getpid() << " quit!" << endl;
			break;
		}
		sleep(1);
	}
}

void Init(vector<Channel> *channels) // 初始化进程池
{
	vector<int> oldfds;
	for (int i = 0; i < processNum; i++)
	{
		int pipefd[2];
		int n = pipe(pipefd); // 创建管道
		(void)n;

		pid_t id = fork();
		if (id == 0) // 子进程
		{
			cout << "child: " << getpid() << " close: " ;
			for (auto& e : oldfds)
			{
				cout << e << " ";
				close(e);
			}
			cout << endl;

			close(pipefd[1]); // 关闭写端
			dup2(pipefd[0], 0);
			Slaver();
			// Slaver(pipefd[0]);
			exit(0);
		}
		// 父进程
		close(pipefd[0]); // 关闭读端

		string name = "process-" + to_string(i);
		channels->push_back(Channel(pipefd[1], id, name)); // 添加channels字段
		oldfds.push_back(pipefd[1]);
	}
}

void Debug(const vector<Channel> &channels)
{
	for (auto &e : channels)
		cout << e._pipefd << " " << e._childpid << " " << e._processname << endl;
}

void Menu()
{
	cout << "###########################" << endl;
	cout << "###1.刷新日志	2.刷新野怪###" << endl;
	cout << "###3.检测更新  4.刷新血量###" << endl;
	cout << "###        0.退出       ###" << endl;
}

void CtrlSlaver(const vector<Channel> &channels)
{
	int processPos = 0;
	for (int processPos = 0; 1 ; processPos++, processPos %= channels.size())
	{
		int select = 0;
		Menu();
		cout << "Please enter: " << endl;
		cin >> select;
		if (select <= 0 || select >= 5)
			break;
		int taskCode = select - 1;
		// 1.选择进程
		// int taskCode = rand() % tasks.size(); 

		// 2.选择进程
		// int processPos = rand() % channels.size(); 

		// 3.发送任务
		cout << "father say taskCode: " << taskCode
			<< " to child: " << channels[processPos]._childpid
			<< ", processName: " << channels[processPos]._processname << endl;
		write(channels[processPos]._pipefd, &taskCode, sizeof(taskCode)); 

		// sleep(1);
	}
}

void QuitProcess(vector<Channel> &channels)
{
	// version 1
	// int last = channels.size() - 1;
	// for (int i = last; i >= 0; i--)
	// {
	// 	close(channels[i]._pipefd);
	// 	waitpid(channels[i]._childpid, nullptr, 0);
	// }

	// version 2


	// for (auto& e : channels)
	// 	close(e._pipefd);
	// // sleep(5);
	// for (auto& e : channels)
	// 	waitpid(e._childpid, nullptr, 0);
}

int main()
{
	srand((unsigned int)time(nullptr) ^ getpid() ^ 1023); // 种一个随机数种子
	vector<Channel> channels;

	// 1.初始化
	LoadTask(&tasks);
	Init(&channels);
	// Debug(channels);

	// 2.控制子进程
	CtrlSlaver(channels);

	// 3.清理收尾
	QuitProcess(channels);

	return 0;
}
